/*
* ISvd.cs
* 
* Copyright (c) 2005, dnAnalytics. All rights reserved.
*/

#region Using Directives

using System;
using dnAnalytics.Math;

#endregion

namespace dnAnalytics.LinearAlgebra.Decomposition
{
    /// <summary>
    /// Interface for computing the Singular Value Decomposition of a <see cref="Matrix"/>.
    /// </summary>
    internal interface ISvd : IAlgorithm
    {
        /// <summary>
        /// Returns whether the decomposition converged or not.
        /// </summary>
        /// <returns><b>true</b> if the decomposition converged; <b>false</b> otherwise.</returns>
        bool Converged();

        ///<summary>Returns the left singular vectors.</summary>
        ///<returns>The left singular vectors. The vectors will be <b>null</b>,
        ///if <b>computeVectors</b> in the constructor is set to false.</returns>
        Matrix U();

        /// <summary>
        /// Copies the left singular vectors into the <paramref name="result"/> <see cref="Matrix"/>.
        /// </summary>
        /// <param name="result">The <see cref="Matrix"/> to copy the left singular vectors into.</param>
        /// <remarks>The method does nothing if <b>computeVectors</b> in the constructor is set to false.</remarks>
        void U(Matrix result);

        ///<summary>Returns the right singular vectors.</summary>
        ///<returns>The right singular vectors. The vectors will be <b>null</b>,
        ///if <b>computeVectors</b> in the constructor is set to false.</returns>
        ///<remarks>This is the transpose of the V matrix.</remarks>
        Matrix VT();

        /// <summary>
        /// Copies the right singular vectors into the <paramref name="result"/> <see cref="Matrix"/>.
        /// </summary>
        /// <param name="result">The <see cref="Matrix"/> to copy the right singular vectors into.</param>
        /// <remarks>The method does nothing if <b>computeVectors</b> in the constructor is set to false.</remarks>
        ///<remarks>This is the transpose of the V matrix.</remarks>
        void VT(Matrix result);

        ///<summary>Returns the singular values as a diagonal <see cref="Matrix"/>.</summary>
        ///<returns>The singular values as a diagonal <see cref="Matrix"/>.</returns>        
        Matrix W();

        /// <summary>
        /// Resets the <paramref name="result"/> <see cref="Matrix"/> and copies the singular values onto the diagonal.
        /// </summary>
        /// <param name="result"><see cref="Matrix"/> to copy the singular values to.</param>
        void W(Matrix result);

        ///<summary>Returns the singular values as a <see cref="Vector"/>.</summary>
        ///<returns>the singular values as a <see cref="Vector"/>.</returns>
        Vector S();

        /// <summary>
        /// Copies the singular values to the given <see cref="Vector"/>.
        /// </summary>
        /// <param name="result">The <see cref="Vector"/> to copy the singular values into.</param>
        void S(Vector result);

        ///<summary>Returns the two norm of the <see cref="Matrix"/>.</summary>
        ///<returns>The two norm of the <see cref="Matrix"/>.</returns>        
        double Norm2();

        ///<summary>Returns the condition number <b>max(S) / min(S)</b>.</summary>
        ///<returns>The condition number.</returns>
        double ConditionNumber();

        ///<summary>Returns the effective numerical matrix rank.</summary>
        ///<returns>The number of non-negligible singular values.</returns>
        int Rank();

        /// <summary>
        /// Finds the least squares solution of <b>A*X = B</b>, where <b>A.Rows &gt;= A.Columns</b>
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
        /// <returns>The left hand side <see cref="Matrix"/>, <b>X</b>.</returns>
        /// <exception cref="InvalidOperationException">The left and right singular values were not computed, 
        /// but they are required for this operation.</exception>
        Matrix Solve(Matrix rightHandSide);

        /// <summary>
        /// Finds the least squares solution of <b>A*X = B</b>, where <b>A.Rows &gt;= A.Columns</b>
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Matrix"/>, <b>B</b>.</param>
        /// <param name="result">The left hand side <see cref="Matrix"/>, <b>X</b>.</param>
        /// <exception cref="InvalidOperationException">The left and right singular values were not computed, 
        /// but they are required for this operation.</exception>
        void Solve(Matrix rightHandSide, Matrix result);

        /// <summary>
        /// Finds the least squares solution of <b>A*x = b</b>, where <b>A.Rows &gt;= A.Columns</b>
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Vector"/>, <b>b</b>.</param>
        /// <returns>The left hand side <see cref="Vector"/>, <b>x</b>.</returns>
        /// <exception cref="InvalidOperationException">The left and right singular values were not computed, 
        /// but they are required for this operation.</exception>
        Vector Solve(Vector rightHandSide);

        /// <summary>
        /// Solves a system of linear equations, <b>Ax = b</b>.
        /// </summary>
        /// <param name="rightHandSide">The right hand side <see cref="Vector"/>, <b>b</b>.</param>
        /// <param name="result">The left hand side <see cref="Vector"/>, <b>x</b>.</param>
        /// <exception cref="InvalidOperationException">The left and right singular values were not computed, 
        /// but they are required for this operation.</exception>
        void Solve(Vector rightHandSide, Vector result);
    }
}
